home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / tsipp / tsipp.lha / tsipp3.0a / src / tSippCamera.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-02  |  11.8 KB  |  352 lines

  1. /*
  2.  *=============================================================================
  3.  *                                tSippCamera.c
  4.  *-----------------------------------------------------------------------------
  5.  * Tcl commands to manage SIPP camera.
  6.  *-----------------------------------------------------------------------------
  7.  * Copyright 1992 Mark Diekhans
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies.  Mark Diekhans makes
  11.  * no representations about the suitability of this software for any purpose.
  12.  * It is provided "as is" without express or implied warranty.
  13.  *-----------------------------------------------------------------------------
  14.  * $Id: tSippCamera.c,v 2.0 1992/11/02 03:56:24 markd Rel $
  15.  *=============================================================================
  16.  */
  17.  
  18. #include "tSippInt.h"
  19. /*
  20.  * Internal function prototypes.
  21.  */
  22. static Camera *
  23. CameraHandleToPtr _ANSI_ARGS_((tSippGlob_pt    tSippGlobPtr,
  24.                                char           *handle));
  25.  
  26. static bool
  27. ProcessCameraParms _ANSI_ARGS_((tSippGlob_pt    tSippGlobPtr,
  28.                                 Camera         *camera,
  29.                                 int             argc,
  30.                                 char          **argv));
  31.  
  32. /*=============================================================================
  33.  * CameraHandleToPtr --
  34.  *   Utility procedure to convert a camera handle to a camera pointer.
  35.  * Parameters:
  36.  *   o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
  37.  *   o handle (I) - A camera handle.
  38.  * Returns:
  39.  *   A pointer to the camera, or NULL if an error occured.
  40.  *-----------------------------------------------------------------------------
  41.  */
  42. static Camera *
  43. CameraHandleToPtr (tSippGlobPtr, handle)
  44.     tSippGlob_pt    tSippGlobPtr;
  45.     char           *handle;
  46. {
  47.     Camera **cameraEntryPtr;
  48.  
  49.     if (STREQU (handle, "STDCAMERA"))
  50.         handle = "camera0";
  51.  
  52.     cameraEntryPtr = (Camera **)
  53.         Tcl_HandleXlate (tSippGlobPtr->interp, 
  54.                          tSippGlobPtr->cameraTblPtr, handle);
  55.     if (cameraEntryPtr == NULL)
  56.         return NULL;
  57.     return *cameraEntryPtr;
  58.  
  59. } /* CameraHandleToPtr */
  60.  
  61. /*=============================================================================
  62.  * ProcessCameraParms --
  63.  *    Process the arguments for the SippCameraCreate and SippCameraParms
  64.  * commands.  These arguments are in the form:
  65.  *    [position] [point] [upvector] [focal]
  66.  *
  67.  * Parameters:
  68.  *   o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
  69.  *   o camera (I) - The apply the parameters to.
  70.  *   o argc (I) - The argument count, only including the arguments to process.
  71.  *   o argv (I) - The argument vector, starting with the first option to
  72.  *     process.
  73.  * Returns:
  74.  *   TRUE is ok, FALSE if an error occured (message in interp).
  75.  *-----------------------------------------------------------------------------
  76.  */
  77. static bool
  78. ProcessCameraParms (tSippGlobPtr, camera, argc, argv)
  79.     tSippGlob_pt    tSippGlobPtr;
  80.     Camera         *camera;
  81.     int             argc;
  82.     char          **argv;
  83. {
  84.     Vector  position, point, upVector, viewVector;
  85.     double  focal, dotProduct;
  86.     bool    setPosition, setPoint, setUp, setFocal;
  87.  
  88.     setPosition = setPoint = setUp = setFocal = FALSE;
  89.     if ((argc > 0) && (argv [0][0] != '\0'))
  90.         setPosition = TRUE;
  91.     if ((argc > 1) && (argv [1][0] != '\0'))
  92.         setPoint = TRUE;
  93.     if ((argc > 2) && (argv [2][0] != '\0'))
  94.         setUp = TRUE;
  95.     if ((argc > 3) && (argv [3][0] != '\0'))
  96.         setFocal = TRUE;
  97.  
  98.     if (setPosition && !TSippConvertVertex (tSippGlobPtr, argv [0], &position))
  99.         return FALSE;
  100.     if (setPoint && !TSippConvertVertex (tSippGlobPtr, argv [1], &point))
  101.         return FALSE;
  102.     if (setUp && !TSippConvertVertex (tSippGlobPtr, argv [2], &upVector))
  103.         return FALSE;
  104.     if (setFocal && (Tcl_GetDouble (tSippGlobPtr->interp, argv [3],
  105.                                     &focal) != TCL_OK))
  106.         return FALSE;
  107.  
  108.     /*
  109.      * Check the the position and point are not the same and that the view
  110.      * and up vectors are not parallel.  First gather the current camera
  111.      * settings for the values that were not specified.
  112.      */
  113.     if (!setPosition)
  114.         position = camera->position;
  115.     if (!setPoint)
  116.         point = camera->lookat;
  117.     if (!setUp)
  118.         upVector = camera->up;
  119.  
  120.     if (FEQUAL (position.x, point.x) && FEQUAL (position.y, point.y) && 
  121.         FEQUAL (position.z, point.z)) {
  122.         Tcl_AppendResult (tSippGlobPtr->interp, "The position and point ",
  123.                           "may not be the same", (char *) NULL);
  124.         return FALSE;
  125.     }
  126.         
  127.     viewVector.x = point.x - position.x;
  128.     viewVector.y = point.y - position.y;
  129.     viewVector.z = point.z - position.z;
  130.     vecnorm (&viewVector);
  131.     vecnorm (&upVector);
  132.  
  133.     dotProduct = fabs (VecDot (viewVector, upVector));
  134.     if (FEQUAL (dotProduct, 1.0)) {
  135.         Tcl_AppendResult (tSippGlobPtr->interp, "The view vector (position ",
  136.                           "to point) and up vector may not be parallel",
  137.                           (char *) NULL);
  138.         return FALSE;
  139.     }
  140.  
  141.     /*
  142.      * Now set the requested values.
  143.      */
  144.     if (setPosition)
  145.         camera_position (camera, position.x, position.y, position.z);
  146.     if (setPoint)
  147.         camera_look_at (camera, point.x, point.y, point.z);
  148.     if (setUp)
  149.         camera_up (camera, upVector.x, upVector.y, upVector.z);
  150.     if (setFocal)
  151.         camera_focal (camera, focal);
  152.     return TRUE;
  153.  
  154. } /* ProcessCameraParms */
  155.  
  156. /*=============================================================================
  157.  * SippCameraCreate --
  158.  *   Implements the command:
  159.  *     SippCameraCreate [position] [point] [upvector] [focal]
  160.  *
  161.  * Note:
  162.  *   This procedure has standard Tcl command calling sematics.  ClientData
  163.  * contains a pointer to the Tcl SIPP global structure.
  164.  *-----------------------------------------------------------------------------
  165.  */
  166. static int
  167. SippCameraCreate (clientData, interp, argc, argv)
  168.     char       *clientData;
  169.     Tcl_Interp *interp;
  170.     int         argc;
  171.     char      **argv;
  172. {
  173.     tSippGlob_pt   tSippGlobPtr = (tSippGlob_pt) clientData;
  174.     Camera        *camera;
  175.     Camera       **cameraEntryPtr;
  176.  
  177.     if (argc > 5) {
  178.         Tcl_AppendResult (interp, "wrong # args: ", argv [0],
  179.                           " [position] [point] [upvector] [focal]",
  180.                           (char *) NULL);
  181.         return TCL_ERROR;
  182.     }
  183.     camera = camera_create ();
  184.     if (!ProcessCameraParms (tSippGlobPtr, camera, argc - 1, &argv [1])) {
  185.         camera_destruct (camera);
  186.         return TCL_ERROR;
  187.     }
  188.     cameraEntryPtr = (Camera **) Tcl_HandleAlloc (tSippGlobPtr->cameraTblPtr,
  189.                                                  tSippGlobPtr->interp->result);
  190.     *cameraEntryPtr = camera;
  191.     return TCL_OK;
  192.  
  193. } /* SippCameraCreate */
  194.  
  195. /*=============================================================================
  196.  * SippCameraDestruct --
  197.  *   Implements the command:
  198.  *     SippCameraDestruct cameralist
  199.  * Note:
  200.  *   This procedure has standard Tcl command calling sematics.  ClientData
  201.  * contains a pointer to the Tcl SIPP global structure.
  202.  *-----------------------------------------------------------------------------
  203.  */
  204. static int
  205. SippCameraDestruct (clientData, interp, argc, argv)
  206.     char       *clientData;
  207.     Tcl_Interp *interp;
  208.     int         argc;
  209.     char      **argv;
  210. {
  211.     tSippGlob_pt    tSippGlobPtr = (tSippGlob_pt) clientData;
  212.     handleList_t    cameraList;
  213.     handleList_t    cameraEntryList;
  214.     int             idx;
  215.  
  216.     if (argc != 2) {
  217.         Tcl_AppendResult (interp, "wrong # args: ", argv [0], " cameralist",
  218.                           (char *) NULL);
  219.         return TCL_ERROR;
  220.     }
  221.     if (!TSippHandleListConvert (tSippGlobPtr, tSippGlobPtr->cameraTblPtr,
  222.                                  argv [1], &cameraList, &cameraEntryList))
  223.         return TCL_ERROR;
  224.  
  225.     for (idx = 0; idx < cameraList.len; idx++) {
  226.         camera_destruct ((Camera *) cameraList.ptr [idx]);
  227.         Tcl_HandleFree (tSippGlobPtr->cameraTblPtr, cameraEntryList.ptr [idx]);
  228.     }
  229.  
  230.     TSippHandleListFree (&cameraList);
  231.     TSippHandleListFree (&cameraEntryList);
  232.     return TCL_OK;
  233.  
  234. } /* SippCameraDestruct */
  235.  
  236. /*=============================================================================
  237.  * SippCameraParams --
  238.  *   Implements the command:
  239.  *     SippCameraParams camera [position] [point] [upvector] [focal]
  240.  *
  241.  * Note:
  242.  *   This procedure has standard Tcl command calling sematics.  ClientData
  243.  * contains a pointer to the Tcl SIPP global structure.
  244.  *-----------------------------------------------------------------------------
  245.  */
  246. static int
  247. SippCameraParams (clientData, interp, argc, argv)
  248.     char       *clientData;
  249.     Tcl_Interp *interp;
  250.     int         argc;
  251.     char      **argv;
  252. {
  253.     tSippGlob_pt   tSippGlobPtr = (tSippGlob_pt) clientData;
  254.     Camera        *camera;
  255.  
  256.     if ((argc < 2) || (argc > 6)) {
  257.         Tcl_AppendResult (interp, "wrong # args: ", argv [0],
  258.                           " camera [position] [point] [upvector] [focal]",
  259.                           (char *) NULL);
  260.         return TCL_ERROR;
  261.     }
  262.     camera = CameraHandleToPtr (tSippGlobPtr, argv [1]);
  263.     if (camera == NULL)
  264.         return TCL_ERROR;
  265.  
  266.     if (!ProcessCameraParms (tSippGlobPtr, camera, argc - 2, &argv [2])) {
  267.         return TCL_ERROR;
  268.     }
  269.     return TCL_OK;
  270.  
  271. } /* SippCameraParams */
  272.  
  273. /*=============================================================================
  274.  * SippCameraUse --
  275.  *   Implements the command:
  276.  *     SippCameraUse camera
  277.  *
  278.  * Note:
  279.  *   This procedure has standard Tcl command calling sematics.  ClientData
  280.  * contains a pointer to the Tcl SIPP global structure.
  281.  *-----------------------------------------------------------------------------
  282.  */
  283. static int
  284. SippCameraUse (clientData, interp, argc, argv)
  285.     char       *clientData;
  286.     Tcl_Interp *interp;
  287.     int         argc;
  288.     char      **argv;
  289. {
  290.     tSippGlob_pt   tSippGlobPtr = (tSippGlob_pt) clientData;
  291.     Camera        *camera;
  292.  
  293.     if (argc != 2) {
  294.         Tcl_AppendResult (interp, "wrong # args: ", argv [0], " camera",
  295.                           (char *) NULL);
  296.         return TCL_ERROR;
  297.     }
  298.     camera = CameraHandleToPtr (tSippGlobPtr, argv [1]);
  299.     if (camera == NULL)
  300.         return TCL_ERROR;
  301.  
  302.     camera_use (camera);
  303.     return TCL_OK;
  304.  
  305. } /* SippCameraUse */
  306.  
  307. /*=============================================================================
  308.  * TSippCameraInit --
  309.  *   Initialized the camera commands and set up STDCAMERA as the current
  310.  * camera.
  311.  *
  312.  * Parameters:
  313.  *   o tclSippGlobP (I) - Pointer to the top level global data structure.
  314.  *     (currently unused).
  315.  *-----------------------------------------------------------------------------
  316.  */
  317. void
  318. TSippCameraInit (tSippGlobPtr)
  319.     tSippGlob_pt    tSippGlobPtr;
  320. {
  321.     Camera        *camera;
  322.     Camera       **cameraEntryPtr;
  323.  
  324.     static tSippTclCmdTbl_t cmdTable [] = {
  325.         {"SippCameraCreate",   SippCameraCreate},
  326.         {"SippCameraDestruct", SippCameraDestruct},
  327.         {"SippCameraParams",   SippCameraParams},
  328.         {"SippCameraUse",      SippCameraUse},
  329.         {NULL,                 NULL}
  330.     };
  331.  
  332.     tSippGlobPtr->cameraTblPtr = 
  333.         Tcl_HandleTblInit ("camera", sizeof (Object *), 24);
  334.  
  335.     TSippInitCmds (tSippGlobPtr, cmdTable);
  336.  
  337.     /*
  338.      * Set up the standard camera entry `STDCAMERA'.  Allocate a new camera
  339.      * rather than useing the SIPP default so it can be deleted.
  340.      */
  341.     camera = camera_create ();
  342.     camera_params (camera, 0.0, 0.0, 10.0,  0.0, 0.0, 0.0,  
  343.                            0.0, 1.0, 0.0,   0.25);
  344.     camera_use (camera);
  345.  
  346.     cameraEntryPtr = (Camera **) Tcl_HandleAlloc (tSippGlobPtr->cameraTblPtr,
  347.                                                  tSippGlobPtr->interp->result);
  348.     *cameraEntryPtr = camera;
  349.  
  350.  
  351. } /* TSippCameraInit */
  352.